package rad.framework.uml2.classdiagram.providers;

import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
import rad.framework.uml2.classdiagram.part.UMLDiagramEditorPlugin;

import org.eclipse.uml2.uml.UMLPackage;

/**
 * @generated
 */
public class UMLElementTypes {

	/**
	 * @generated
	 */
	private UMLElementTypes() {
	}

	/**
	 * @generated
	 */
	private static Map elements;

	/**
	 * @generated
	 */
	private static ImageRegistry imageRegistry;

	/**
	 * @generated
	 */
	private static ImageRegistry getImageRegistry() {
		if (imageRegistry == null) {
			imageRegistry = new ImageRegistry();
		}
		return imageRegistry;
	}

	/**
	 * @generated
	 */
	private static String getImageRegistryKey(ENamedElement element) {
		return element.getName();
	}

	/**
	 * @generated
	 */
	private static ImageDescriptor getProvidedImageDescriptor(
			ENamedElement element) {
		if (element instanceof EStructuralFeature) {
			element = ((EStructuralFeature) element).getEContainingClass();
		}
		if (element instanceof EClass) {
			EClass eClass = (EClass) element;
			if (!eClass.isAbstract()) {
				return UMLDiagramEditorPlugin.getInstance()
						.getItemImageDescriptor(
								eClass.getEPackage().getEFactoryInstance()
										.create(eClass));
			}
		}
		// TODO : support structural features
		return null;
	}

	/**
	 * @generated
	 */
	public static ImageDescriptor getImageDescriptor(ENamedElement element) {
		String key = getImageRegistryKey(element);
		ImageDescriptor imageDescriptor = getImageRegistry().getDescriptor(key);
		if (imageDescriptor == null) {
			imageDescriptor = getProvidedImageDescriptor(element);
			if (imageDescriptor == null) {
				imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
			}
			getImageRegistry().put(key, imageDescriptor);
		}
		return imageDescriptor;
	}

	/**
	 * @generated
	 */
	public static Image getImage(ENamedElement element) {
		String key = getImageRegistryKey(element);
		Image image = getImageRegistry().get(key);
		if (image == null) {
			ImageDescriptor imageDescriptor = getProvidedImageDescriptor(element);
			if (imageDescriptor == null) {
				imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
			}
			getImageRegistry().put(key, imageDescriptor);
			image = getImageRegistry().get(key);
		}
		return image;
	}

	/**
	 * @generated
	 */
	public static ImageDescriptor getImageDescriptor(IAdaptable hint) {
		ENamedElement element = getElement(hint);
		if (element == null) {
			return null;
		}
		return getImageDescriptor(element);
	}

	/**
	 * @generated
	 */
	public static Image getImage(IAdaptable hint) {
		ENamedElement element = getElement(hint);
		if (element == null) {
			return null;
		}
		return getImage(element);
	}

	/**
	 * Returns 'type' of the ecore object associated with the hint.
	 * 
	 * @generated
	 */
	public static ENamedElement getElement(IAdaptable hint) {
		Object type = hint.getAdapter(IElementType.class);
		if (elements == null) {
			elements = new IdentityHashMap();
			elements.put(Package_79, UMLPackage.eINSTANCE.getPackage());
			elements.put(Property_2001, UMLPackage.eINSTANCE.getProperty());
			elements.put(EnumerationLiteral_2002, UMLPackage.eINSTANCE
					.getEnumerationLiteral());
			elements.put(Operation_2003, UMLPackage.eINSTANCE.getOperation());
			elements.put(Class_1001, UMLPackage.eINSTANCE.getClass_());
			elements.put(Enumeration_1002, UMLPackage.eINSTANCE
					.getEnumeration());
			elements.put(Interface_1003, UMLPackage.eINSTANCE.getInterface());
			elements.put(Actor_1004, UMLPackage.eINSTANCE.getActor());
			elements.put(UseCase_1005, UMLPackage.eINSTANCE.getUseCase());
			elements.put(Generalization_3001, UMLPackage.eINSTANCE
					.getGeneralization());
			elements.put(Association_3002, UMLPackage.eINSTANCE
					.getAssociation());
			elements.put(Association_3003, UMLPackage.eINSTANCE
					.getAssociation());
			elements.put(Association_3004, UMLPackage.eINSTANCE
					.getAssociation());
			elements.put(Association_3005, UMLPackage.eINSTANCE
					.getAssociation());
			elements.put(Association_3006, UMLPackage.eINSTANCE
					.getAssociation());
			elements.put(Dependency_3007, UMLPackage.eINSTANCE.getDependency());
		}
		return (ENamedElement) elements.get(type);
	}

	/**
	 * @generated
	 */
	public static final IElementType Package_79 = getElementType("rad.framework.uml2.classdiagram.Package_79"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Property_2001 = getElementType("rad.framework.uml2.classdiagram.Property_2001"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType EnumerationLiteral_2002 = getElementType("rad.framework.uml2.classdiagram.EnumerationLiteral_2002"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Operation_2003 = getElementType("rad.framework.uml2.classdiagram.Operation_2003"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Class_1001 = getElementType("rad.framework.uml2.classdiagram.Class_1001"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Enumeration_1002 = getElementType("rad.framework.uml2.classdiagram.Enumeration_1002"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Interface_1003 = getElementType("rad.framework.uml2.classdiagram.Interface_1003"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Actor_1004 = getElementType("rad.framework.uml2.classdiagram.Actor_1004"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType UseCase_1005 = getElementType("rad.framework.uml2.classdiagram.UseCase_1005"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Generalization_3001 = getElementType("rad.framework.uml2.classdiagram.Generalization_3001"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Association_3002 = getElementType("rad.framework.uml2.classdiagram.Association_3002"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Association_3003 = getElementType("rad.framework.uml2.classdiagram.Association_3003"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Association_3004 = getElementType("rad.framework.uml2.classdiagram.Association_3004"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Association_3005 = getElementType("rad.framework.uml2.classdiagram.Association_3005"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Association_3006 = getElementType("rad.framework.uml2.classdiagram.Association_3006"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Dependency_3007 = getElementType("rad.framework.uml2.classdiagram.Dependency_3007"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	private static IElementType getElementType(String id) {
		return ElementTypeRegistry.getInstance().getType(id);
	}

	/**
	 * @generated
	 */
	private static Set KNOWN_ELEMENT_TYPES;

	/**
	 * @generated
	 */
	public static boolean isKnownElementType(IElementType elementType) {
		if (KNOWN_ELEMENT_TYPES == null) {
			KNOWN_ELEMENT_TYPES = new HashSet();
			KNOWN_ELEMENT_TYPES.add(Package_79);
			KNOWN_ELEMENT_TYPES.add(Property_2001);
			KNOWN_ELEMENT_TYPES.add(EnumerationLiteral_2002);
			KNOWN_ELEMENT_TYPES.add(Operation_2003);
			KNOWN_ELEMENT_TYPES.add(Class_1001);
			KNOWN_ELEMENT_TYPES.add(Enumeration_1002);
			KNOWN_ELEMENT_TYPES.add(Interface_1003);
			KNOWN_ELEMENT_TYPES.add(Actor_1004);
			KNOWN_ELEMENT_TYPES.add(UseCase_1005);
			KNOWN_ELEMENT_TYPES.add(Generalization_3001);
			KNOWN_ELEMENT_TYPES.add(Association_3002);
			KNOWN_ELEMENT_TYPES.add(Association_3003);
			KNOWN_ELEMENT_TYPES.add(Association_3004);
			KNOWN_ELEMENT_TYPES.add(Association_3005);
			KNOWN_ELEMENT_TYPES.add(Association_3006);
			KNOWN_ELEMENT_TYPES.add(Dependency_3007);
		}
		return KNOWN_ELEMENT_TYPES.contains(elementType);
	}
}
